package com.headwire.kw.helpers;

import java.util.Map;
import java.util.Map.Entry;

public class TestHelper {
	public static final String KEY = "%k$";
	public static final String VALUE = "%v$";
	public static final String NEWLINE = "\n";
	
	public String outputMapFmt(Map m, String formatString) {
		return outputMapFmt(m,formatString,NEWLINE);
	}
	
	// format for string variables, %k$ = key, %v$ = value
	public String outputMapFmt(Map m, String formatString, String lineDelimiter) {
		String[] format = getFormatArray(formatString);
		StringBuilder sb = new StringBuilder();
		
		for(Object k : m.keySet()) {
			for(int i = 0; i < format.length; i++) {
				if(format[i].equals(KEY))
					sb.append(k);
				else if(format[i].equals(VALUE))
					sb.append(m.get(k));
				else
					sb.append(format[i]);
				sb.append(lineDelimiter);
			}
		}
		
		return sb.toString();
	}
	
	public String[] getFormatArray(String format) {
		// state machine woooo
		boolean inVar = false;
		boolean escape = false;
		
		String[] fmt = new String[5];
		StringBuilder sb = new StringBuilder();
		int index = 0;
		for(int i = 0; i < format.length(); i++) {
			char c = format.charAt(i);
			if(escape) {
				sb.append(c);
				escape = false;
				continue;
			}
			if(inVar) {
				if(c == '$') {
					inVar = false;
					sb.append(c);
					fmt = ensureCapacity(fmt,index+1);
					fmt[index] = sb.toString();
					sb = new StringBuilder();
					index++;
					continue;
				}
				else {
					sb.append(c);
					continue;
				}
			}
			if(c == '\\') {
				escape = true;
				sb.append(c);
				continue;
			}
			if(c == '%') {
				inVar = true;
				fmt = ensureCapacity(fmt,index+1);
				fmt[index] = sb.toString();
				sb = new StringBuilder();
				index++;
				sb.append(c);
				continue;
			}
		}
		
		return shrink(fmt);
	}
	
	private String[] shrink(String[] array) {
		// remove all nulls
		int size = array.length;
		for(int i = 0; i < array.length; i++) {
			if(array[i] == null) {
				size = i;
				break;
			}
		}
		if(size < array.length) {
			String[] na = new String[size];
			for(int i = 0; i < na.length; i++) {
				na[i] = array[i];
			}
			return na;
		}
		return array;
	}
	
	// since this method is internal we'll overboost capacity
	private String[] ensureCapacity(String[] array, int size) {
		if(size <= array.length)
			return array;
		int newSize = (int) (size*1.5);
		String[] na = new String[newSize];
		for(int i = 0; i < array.length; i++) {
			na[i] = array[i];
		}
		return na;
	}
}
